package com.dd.keel.core.common.utils;


import java.lang.reflect.*;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Iterator;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ClassUtil {
	
	final static private Logger LOGGER = LoggerFactory.getLogger(ClassUtil.class);
	
	public static Class getClass(String className,ClassLoader loader) throws Exception
	{
		if(className==null || className.equals("")) return null;
        Class oneClass = loader.loadClass(className);
		return oneClass;
	}
	
	public static Class getClass(String className) throws Exception
	{
		if(className==null || className.equals("")) return null;
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        Class oneClass = loader.loadClass(className);
		return oneClass;
	}
	
	public static Object newInstance(Class oneClass) throws Exception
	{
		if(oneClass==null) return null;
        Object oneObject = oneClass.newInstance();
		return oneObject;
	}
	
    public static Object invokeMethod(Object owner, String methodName, Object[] args) throws Exception
	{
    	if(owner==null) return null;
		Class ownerClass = owner.getClass();
		Class[] argsClass = new Class[args.length];
		for (int i = 0, j = args.length; i < j; i++) {
			argsClass[i] = args[i].getClass();
		}
		Method method = ownerClass.getMethod(methodName, argsClass);
		if(method!=null)
		{
			return method.invoke(owner, args);
		}
		return null;
	}
    
    public static void injectFields(Object owner, Map<String,Object> fields)
    {
    	if(owner!=null && fields!=null && !fields.isEmpty())
    	{
    		String methodName = null;
    		Iterator<String> fieldNameIter = fields.keySet().iterator();
    		while(fieldNameIter.hasNext())
    		{
    			String fieldName = fieldNameIter.next();
    			methodName = "set"+Character.toUpperCase(fieldName.charAt(0))+fieldName.substring(1);
    			try{
    				invokeMethod( owner, methodName, new Object[]{fields.get(fieldName)} );
    			}catch(Exception ex){
    				LOGGER.error(ex.getMessage(), ex);
    			}
    		}
    	}
    }
    
    public static Object getterObject(Object obj,String methodName)
    {
    	if(obj==null) return null;
    	Class objClass = obj.getClass();
		try {
			Method mtd = objClass.getMethod(methodName, new Class[]{});
    		Object value = mtd.invoke(obj, new Object[]{});
    		if(value!=null)
    		{
    			return value;
    		}
		} catch (SecurityException ex) {
			LOGGER.error(ex.getMessage(), ex);
		} catch (NoSuchMethodException ex) {
			LOGGER.error(ex.getMessage(), ex);
		} catch (IllegalArgumentException ex) {
			LOGGER.error(ex.getMessage(), ex);
		} catch (IllegalAccessException ex) {
			LOGGER.error(ex.getMessage(), ex);
		} catch (InvocationTargetException ex) {
			LOGGER.error(ex.getMessage(), ex);
		}
		return null;
    }
    
    public static Properties getFields(Object obj,String[] fieldNames) 
    {
    	Properties reqFields = new Properties();
    	String methodName = null;
    	Class objClass = obj.getClass();
    	for(int i=0; i<fieldNames.length; ++i)
    	{
    		methodName = fieldNames[i];
    		methodName = "get"+Character.toUpperCase(methodName.charAt(0))+methodName.substring(1);
    		Method mtd;
			try {
				mtd = objClass.getMethod(methodName, new Class[]{});
	    		Object value = mtd.invoke(obj, new Object[]{});
	    		if(value!=null)
	    		{
	    			reqFields.put(fieldNames[i], value);
	    		}
			} catch (SecurityException ex) {
				LOGGER.error(ex.getMessage(), ex);
			} catch (NoSuchMethodException ex) {
				LOGGER.error(ex.getMessage(), ex);
			} catch (IllegalArgumentException ex) {
				LOGGER.error(ex.getMessage(), ex);
			} catch (IllegalAccessException ex) {
				LOGGER.error(ex.getMessage(), ex);
			} catch (InvocationTargetException ex) {
				LOGGER.error(ex.getMessage(), ex);
			}
    	}
    	return reqFields;
    }

	public static Object getField(Object obj, String fieldName) {
		String methodName = null;
		Object value = null;
		Class objClass = obj.getClass();
		methodName = fieldName;
		methodName = "get" + Character.toUpperCase(methodName.charAt(0))
				+ methodName.substring(1);
		Method mtd;
		try {
			mtd = objClass.getMethod(methodName, new Class[] {});
			value = mtd.invoke(obj, new Object[] {});
		} catch (SecurityException ex) {
			LOGGER.error(ex.getMessage(), ex);
		} catch (NoSuchMethodException ex) {
			LOGGER.error(ex.getMessage(), ex);
		} catch (IllegalArgumentException ex) {
			LOGGER.error(ex.getMessage(), ex);
		} catch (IllegalAccessException ex) {
			LOGGER.error(ex.getMessage(), ex);
		} catch (InvocationTargetException ex) {
			LOGGER.error(ex.getMessage(), ex);
		}
		return value;
	}
    
    public static void setFields(Object obj,Properties fieldValues) 
    {
    	String methodName = null;
    	Class objClass = obj.getClass();
    	if(fieldValues!=null && !fieldValues.isEmpty())
    	{
    		Enumeration keys = fieldValues.keys();
    		while(keys.hasMoreElements())
    		{
    			String key = (String)keys.nextElement();
    			Object value = fieldValues.getProperty(key);
    			if(value!=null)
    			{
    		    	methodName = key;
    		    	methodName = "set"+Character.toUpperCase(methodName.charAt(0))+methodName.substring(1);
    	        	Method mtd;
					try {
						mtd = objClass.getMethod(methodName, new Class[]{String.class});
						mtd.invoke(obj, new Object[]{value});
					} catch (SecurityException ex) {
						LOGGER.error(ex.getMessage(), ex);
					} catch (NoSuchMethodException ex) {
						LOGGER.error(ex.getMessage(), ex);
					} catch (IllegalArgumentException ex) {
						LOGGER.error(ex.getMessage(), ex);
					} catch (IllegalAccessException ex) {
						LOGGER.error(ex.getMessage(), ex);
					} catch (InvocationTargetException ex) {
						LOGGER.error(ex.getMessage(), ex);
					}
    			}
    		}
    	}
    }
	
}
